﻿using System;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Threading;
using System.Collections.Generic;

namespace ljtx
{
    public partial class ljtxMain : Form
    {
        #region 属性

        private HttpSocket socket;
        private BaseUrl baseUrl;
        private StringBuilder cookies;
        private UserInfo userInfo;
        private PersonInfo personInfo;
        private ServerInfo serverInfo;

        #endregion

        #region 事件

        #region 初始化
        public ljtxMain()
        {
            InitializeComponent();
            baseUrl = new BaseUrl();
            cookies = new StringBuilder();
            userInfo = new UserInfo();
            personInfo = new PersonInfo();
            serverInfo = new ServerInfo();

            this.btnTuiChu.Enabled = false;

            //设置服务器
            foreach (KeyValuePair<string, string> kvp in serverInfo.DicServerAddress_A)
            {
                this.cbxFuWuQi.Items.Add(kvp.Key);
            }
            //设置分区
            foreach (KeyValuePair<string, string> kvp in serverInfo.DicGameAddress_A)
            {
                this.cbxQu.Items.Add(kvp.Key);
            }
        }
        #endregion

        #region 登陆框

        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbxYanZhengMa_MouseClick(object sender, MouseEventArgs e)
        {
            this.tbxYanZhengMa.Text = "";

            this.addTiShi("正在获取验证码，请稍候........\r\n");
            socket = baseUrl.GetForm(serverInfo.DicServerAddress_A[this.cbxFuWuQi.Text.ToString()], "/logout.php", "http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/g_login.php", false);//初始化用户信息

            socket = baseUrl.GetForm(serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()], @"/hs_login.php", @"http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/hs_login.php", false);//进入登陆窗口
            baseUrl.Cookies = socket.SetCookies(new StringBuilder(@"user_lvl=2;cf="));//更新Cookies

            socket = baseUrl.GetForm(serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()], @"/image.php?t=4", @"http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "g_login.php", true);//获取验证码图片
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies

            Console.WriteLine(baseUrl.Cookies);
            pictureBox1.Image = socket.Image;//显示验证码
            this.btnDengLu.Enabled = true;
            this.addTiShi("恭喜：获取验证码成功\r\n");//添加提示

        }


        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDengLu_Click(object sender, EventArgs e)
        {
            userInfo.YongHuMing = this.cbxYongHuMing.Text;
            userInfo.MiMa = this.tbxMiMa.Text;
            userInfo.FuWuQi = this.cbxFuWuQi.Text;
            userInfo.Qu = this.cbxQu.Text;
            userInfo.JiaoSe = this.cbxJueSe.Text;
            userInfo.YanZhengMa = this.tbxYanZhengMa.Text;

            this.addTiShi("用户名：");
            this.addTiShi(userInfo.YongHuMing);
            this.addTiShi("密码：");
            this.addTiShi("*******");
            this.addTiShi("服务器：");
            this.addTiShi(userInfo.FuWuQi);
            this.addTiShi("区：");
            this.addTiShi(userInfo.Qu);
            this.addTiShi("角色：");
            this.addTiShi(userInfo.JiaoSe);
            this.addTiShi("验证码：");
            this.addTiShi(userInfo.YanZhengMa);
            this.addTiShi("\r\n");

            this.btnDengLu.Enabled = false;
            this.btnTuiChu.Enabled = true;

            addTiShi("正在登陆，请稍候.......\r\n");
            socket = baseUrl.GetForm(
                serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()],
                @"/check_user_login.php?user_name=" +
                userInfo.YongHuMing +
                @"&user_passwd=" +
                userInfo.MiMa +
                @"&pps_cryptnum=" +
                userInfo.YanZhengMa,
                "http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/g_login.php", false);//登陆判断 GET

            if (socket.Body == "0") addTiShi("恭喜：可以登陆服务器！\r\n");
            if (socket.Body == "1") addTiShi("参数错误，请重新登陆!\r\n");
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies

            addTiShi("正在登陆服务器.......\r\n");
            socket = baseUrl.PostForm(
                serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()],
                @"/user_login.php",
                "http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/g_login.php",
                @"preurl=http%3A%2F%2F" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + @"%2Fhs_login.php&user_name=" +
                userInfo.YongHuMing +
                @"&user_passwd=" +
                userInfo.MiMa +
                @"&pps_cryptnum=" +
                userInfo.YanZhengMa);//登陆 POST
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies 
            addTiShi("恭喜：登陆服务器成功!\r\n");

            addTiShi("开始登陆服务器........\r\n");
            socket = baseUrl.GetForm(serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()], @"/togame_hs_enter.php?type=151", @" http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/hs_login.php", false);//登陆成功，获取游戏配置信息
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies
            addTiShi("恭喜：登陆服务器成功！\r\n");

            addTiShi("开始登陆游戏........\r\n");
            StringBuilder sb = new StringBuilder();
            sb.Append("accName=");
            sb.Append(queryValueType(socket.Body, "input", "name", "accName", "value"));
            sb.Append(@"&");
            sb.Append("pid=");
            sb.Append(queryValueType(socket.Body, "input", "name", "pid", "value"));
            sb.Append(@"&");
            sb.Append("time=");
            sb.Append(queryValueType(socket.Body, "input", "name", "time", "value"));
            sb.Append(@"&");
            sb.Append("flag=");
            sb.Append(queryValueType(socket.Body, "input", "name", "flag", "value"));
            socket = baseUrl.PostForm(
                @serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()],
                @"/sword/permitAction.action",
                @"http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/togame_hs_enter.php?type=151",
                sb.ToString());//登陆 POST
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies 
            addTiShi("恭喜：登陆游戏成功！\r\n");

            addTiShi("开始获取游戏角色.........\r\n");
            socket = baseUrl.GetForm(serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()], "/sword/loginGame.action?accName=" + queryValue(socket.Body, "action\\?accName=", "\\?manuURL"), "http://" + serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()] + "/sword/permitAction.action", false);//获取登陆的角色信息
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies 
            addTiShi("恭喜：获取角色成功\r\n");

            //获取角色登陆信息
            addTiShi("开始选择角色，并且进入游戏..........\r\n");
            personInfo.UserId = "" + queryValue(socket.Body, "userId=\\'", "\\' userName=","1");
            personInfo.UserName = "" + queryValue(socket.Body, "userName=\\'", "\\'>","1");
            socket = baseUrl.GetForm(serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()], "/sword/playerLoginGame.action?userId=" + personInfo.UserId, " http://" + serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()] + "/sword/permitAction.action", false);//选择要登陆的角色
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies 
            addTiShi("恭喜：选择角色成功，并且成功进入游戏！\r\n");

            //Console.WriteLine("头：" + socket.Header);
            //Console.WriteLine("体：" + socket.Body);
            //Console.WriteLine("cookies：" + baseUrl.Cookies);
            //addTiShi("" + socket.Body);
            this.gbxDengLuKuang.Enabled = false;
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTuiChu_Click(object sender, EventArgs e)
        {
            addTiShi("正在退出，请稍候.......\r\n");
            StringBuilder sb = new StringBuilder(@"pps_cryptnum=_043RlU6Z_3F; user_name=heyu5201; user_pass=3655508db31eb5f9; user_face=http%3A%2F%2Fupload.ppstream.com%2Fsns%2Fimages%2Fuser_face%2F100%2F15.jpg; PPS_TV_I=f53e05056d8ad141e4d2a63be0daf4a6");
            baseUrl.Cookies = socket.SetCookies(sb);
            socket = baseUrl.GetForm(serverInfo.DicServerAddress_A[this.cbxFuWuQi.Text.ToString()], "/logout.php", "http://" + serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()] + "/g_login.php", false);//初始化用户信息
            addTiShi("退出成功\r\n");
            this.btnTuiChu.Enabled = false;
            this.btnDengLu.Enabled = true;
            this.gbxDengLuKuang.Enabled = true;
        }

        #endregion

        #region 配置
        /// <summary>
        /// 获取全地图信息
        /// 只有在游戏地图更新后才使用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetAllMapInfo_Click(object sender, EventArgs e)
        {
            //Thread.Sleep(100);

            Console.WriteLine(serverInfo.DicServerAddress_B[this.cbxFuWuQi.Text.ToString()]);
        }
        #endregion

        #endregion

        #region 方法

        #region 编码转换
        public string UTF8ToGB2312(string str)
        {
            try
            {
                Encoding utf8 = Encoding.GetEncoding(65001);
                Encoding gb2312 = Encoding.GetEncoding("gb2312");//Encoding.Default ,936
                byte[] temp = utf8.GetBytes(str);
                byte[] temp1 = Encoding.Convert(utf8, gb2312, temp);
                string result = gb2312.GetString(temp1);
                return result;
            }
            catch (Exception ex)//(UnsupportedEncodingException ex)
            {
                MessageBox.Show(ex.ToString());
                return null;
            }
        }
        public string GB2312ToUTF8(string str)
        {
            try
            {
                Encoding uft8 = Encoding.GetEncoding(65001);
                Encoding gb2312 = Encoding.GetEncoding("gb2312");
                byte[] temp = gb2312.GetBytes(str);
                byte[] temp1 = Encoding.Convert(gb2312, uft8, temp);
                string result = uft8.GetString(temp1);
                return result;
            }
            catch (Exception ex)//(UnsupportedEncodingException ex)
            {
                MessageBox.Show(ex.ToString());
                return null;
            }
        }
        #endregion

        #region 提示栏

        /// <summary>
        /// 添加信息提示
        /// </summary>
        private void addTiShi(String tishi)
        {
            this.tbxTiShi.AppendText(tishi);
        }

        /// <summary>
        /// 清空提示栏
        /// </summary>
        private void clearTiShi()
        {
            this.tbxTiShi.Clear();
        }
        #endregion

        #region 查找数据
        /// <summary>
        /// 查找str在data中出现的次数
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private int queryConut(String data, String str)
        {
            //data = "    parseInt(startNo) -1) <= 21){ dfd\r\n parseInt\r\n parseInt\r\n parseInt ";
            int count = 0;
            Match m = Regex.Match(data, ".*" + str + ".*");
            while (m.Success)
            {
                count++;
                m = m.NextMatch();
            }
            return count;
        }
        /// <summary>
        /// 根据提供的html数据data,查找类型为controlType，其中一个键值对为name=nameValue的控件对应的valueName键的值
        /// "<input type="hidden" name="accName" id="accName" value="MTDMXsccDtA=" />"
        /// </summary>
        /// <param name="data"></param>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private String queryValueType(String data, String controlType, String name, String nameValue, String valueName)
        {
            String re;
            //String str = 
            //    "<input type=\"hidden\" name=\"accName\" id=\"accName\"  value=\"MTMxMDQxMTA=\" />\r\n" + 
            //    "<input type=\"hidden\" name=\"pid\" id=\"pid\"  value=\"120006\" />\r\n" + 
            //    "<input type=\"hidden\" name=\"time\" id=\"time\"  value=\"1237127004\" />\r\n" + 
            //    "<input type=\"hidden\" name=\"flag\" id=\"flag\"  value=\"5c8f4a8ea12edb7527ed8eb29f5d4cdb\" />\r\n";
            //data = str;
            Match m = Regex.Match(data, "<" + controlType + ".*" + name + "=\"" + nameValue + "\"" + ".*/>");
            Match m2 = Regex.Match(m.Value, valueName + "=\"([\\s\\S]*)\"");
            re = m2.Groups[1].ToString();
            re.Replace("=", @"%3D");
            return re;
        }

        /// <summary>
        /// 根据提供的pre，last匹配数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pre"></param>
        /// <param name="last"></param>
        /// <returns></returns>
        private String queryValue(String data, String pre, String last)
        {
            //String str = "	<script>\r\nloadLogin = function(){\r\n	if(\"\" == null || \"\" == \"\"){\r\nwindow[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006\";\r\n			}else{\r\n				window[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006?manuURL=\'\'&errorInfo=\'\'\";\r\n			}\r\n		};\r\n		window.onload = function(){\r\n			setTimeout(loadLogin, 100);\r\n		};\r\n	</script>\r\n ";
            Match m = Regex.Match(data, ".*" + pre + "(.*)" + last + ".*");
            return m.Groups[1].ToString();
        }

        /// <summary>
        /// 根据提供的pre，last，number查找第number号角色
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pre"></param>
        /// <param name="last"></param>
        /// <returns></returns>
        private String queryValue(String data, String pre, String last,String number)
        {
            //String str = "	<script>\r\nloadLogin = function(){\r\n	if(\"\" == null || \"\" == \"\"){\r\nwindow[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006\";\r\n			}else{\r\n				window[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006?manuURL=\'\'&errorInfo=\'\'\";\r\n			}\r\n		};\r\n		window.onload = function(){\r\n			setTimeout(loadLogin, 100);\r\n		};\r\n	</script>\r\n ";
            Match m= Regex.Match(data, ".*" + pre + "(.*)" + last + ".*");
            for (int i = 0; i < number - 1; i++)
            {
                m = m.NextMatch();
            }

            return m.Groups[1].ToString();
        }

        /// <summary>
        /// 根据提供的pre，last用reg模式匹配数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pre"></param>
        /// <param name="last"></param>
        /// <param name="reg"></param>
        /// <returns></returns>
        private String queryValue(String data, String pre, String last, RegexOptions reg)
        {
            //String str = "	<script>\r\nloadLogin = function(){\r\n	if(\"\" == null || \"\" == \"\"){\r\nwindow[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006\";\r\n			}else{\r\n				window[\'primaryFrame\'].location.href = \"loginGame.action?accName=13104110_120006?manuURL=\'\'&errorInfo=\'\'\";\r\n			}\r\n		};\r\n		window.onload = function(){\r\n			setTimeout(loadLogin, 100);\r\n		};\r\n	</script>\r\n ";
            Match m = Regex.Match(data, ".*" + pre + "(.*)" + last + ".*", reg);
            return m.Groups[1].ToString();
        }

        /// <summary>
        /// 传入 xxx/yyy 形式的字符串。取出xxx值
        /// </summary>
        /// <param name="blood"></param>
        /// <returns></returns>
        private String queryBlood(String blood)
        {
            Match m = Regex.Match(blood, "(.*)/.*");
            return m.Groups[1].ToString();
        }
        #endregion

        #region 游戏操作
        /// <summary>
        /// 获取玩家信息
        /// </summary>
        private HttpSocket getGamerInfo()
        {
            addTiShi("开始获取游戏角色信息..........\r\n");
            socket = baseUrl.GetForm(serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()], "/sword/hero-equip.action", "http://" + serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()] + "/sword/enter-cityImpl.action", false);//获取登陆的角色信息
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies 
            addTiShi("恭喜：获取角色信息成功\r\n");
            return socket;
        }

        /// <summary>
        /// 获取玩家家将信息
        /// </summary>
        /// <returns></returns>
        private HttpSocket getGameNpcInfo()
        {
            return null;
        }

        /// <summary>
        /// 获取当前地图信息
        /// 这个方法只能在登陆后才能起作用。
        /// </summary>
        /// <returns></returns>
        private HttpSocket getMapInfo()
        {
            return baseUrl.GetForm(serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()], "/sword/enter-cityImpl.action", "http://" + serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()] + "/sword/enter-cityImpl.action", false);//获取当前地图信息
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies
        }

        /// <summary>
        /// 攻击npc
        /// </summary>
        /// <returns></returns>
        private HttpSocket attPerson(String sceId)
        {
            return baseUrl.GetForm(serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()], "/sword/battle-attackMonster.action?sceneId=" + sceId, "http://" + serverInfo.DicGameAddress_A[this.cbxQu.Text.ToString()] + "/sword/enter-cityImpl.action", false);//攻击npc
            baseUrl.Cookies = socket.SetCookies(baseUrl.Cookies);//更新Cookies
        }
        #endregion

        #region 功能

        #region 攻击固定npc
        String sceId = "1";
        /// <summary>
        /// 攻击npc
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //String strAttName = textBox1.Text.ToString().Trim();
            //Console.WriteLine(strAttName);
            //sceId = queryValue(getMapInfo().Body, @"MONSTER' sceId='", "' sceName=\"" + strAttName);//获取npcid
            //Console.WriteLine(sceId);
            //addTiShi("英雄现在血量：" + queryValue(getGamerInfo().Body, "bloodValue\" class=\"number\">", "</div></div>") + "\r\n");
            //String hs = attPerson(sceId).Body;//攻击
            //int count = queryConut(hs, "parseInt") + 12;//开始攻击，同时计算攻击所需时间
            //addTiShi("开始攻击：" + strAttName + "。需要时间：" + count + "秒。\r\n");
            //Console.WriteLine(UTF8ToGB2312("\u523A\u5BA2"));
            ////System.Timers.Timer t = new System.Timers.Timer(int.Parse(sceId));//实例化Timer类，配置间隔时间为10000毫秒； 
            ////t.Elapsed += new System.Timers.ElapsedEventHandler(theout);//到达时间的时候执行事件； 
            ////t.AutoReset = false;//配置是执行一次（false）还是一直执行(true)； 
            ////t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件； 

        }


        /// <summary>
        /// 获取此地图可以攻击的npc
        ///     存入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            Console.WriteLine(getMapInfo().Body);
        }
        #endregion

        #endregion

        #endregion

        //Dictionary<(Of <(TKey, TValue>)>) 

        #region 功能

        #endregion
    }
}
